module mculib.arm.builtins;

/**
* 内置函数 
* 嵌入汇编
*/

public import ldc.gccbuiltins_arm;

import mculib.arm.misc;

import ldc.intrinsics;
import ldc.llvmasm:__asm;

version(LDC){}else static assert(0,"Unsupported compiler");


pragma(inline,_inline)
nothrow 
@nogc
@trusted :

/// 设置断点
void  __bkpt() =>  __asm("bkpt", "");

/// 使能FAULT中断;
void enable_fault_irq()  => __asm("cpsie f","");

/// 禁止FAULT中断;
void disable_fault_irq() => __asm("cpsid f","");

/// 清除PRIMASK(使能中断);

void enable_irq()   => __asm("cpsie i","");

/// 设置PRIMASK(禁止中断);
void disable_irq()   => __asm("cpsid i","");
/// 数据存储器屏障，确保在新的存储器访问开始之前，所有的存储器访问已经完成。在符合CMSIS的设备驱动库中，可以使用“__DMB”函数实现该操作

void __dmb()  => __builtin_arm_dmb(0xF);

/// 数据同步屏障，确保在下一条指令开始执行前，所有的存储器访问已经完成。在符合CMSIS的设备驱动库中，可以使用“__DSB”函数实现该操作
void __dsb() => __builtin_arm_dsb(0xF);
/// 指令同步屏障，清除流水线并且确保在新指令执行时，之前的指令都已经执行完毕。在符合CMSIS的设备驱动库中，可以使用“__ISB”函数实现该操作

void __isb() => __builtin_arm_isb(0xF);

/// 无操作指令
void __nop()  => __asm("nop","");

/// 多处理器环境中向所有的处理器发送事件(包括自身)。在符合CMSIS的设备驱动库中，可以使用“__SEV()”实现该操作
void __sev() => __asm("sev","");

/// 等待事件，如果没有之前该事件的记录，进入休眠模式；如果有的话，则清除事件锁存并继续执行；在符合CMSIS的设备驱动库中，可以使用“__WFE()”函数实现该操作，不过若你使用供应商特定的休眠模式，效果会更好
void __wfe() => __asm("wfe","");

/// 等待中断，进入休眠模式。在符合CMSIS的设备驱动库中，可以使用“__WFI()”实现该操作，不过若你使用供应商特定的休眠模式，效果会更好
void __wfi() => __asm("wfi","");

/// 反向字节序，将一个32位的值的字节序反转，如0x12345678变成0x78563412
uint __rev(in uint val) => llvm_bswap(val);

/// YIELD 用于线程切换，表明任务被延迟了，在Cortex-M0上效果和NOP一样

/// 读取指定寄存器模板
uint __getReg(string regName)()
{
    return __asm!uint("mrs $0,"~regName,"=r,~{memory}");
}

/*
uint __getReg(string reg,bool mem = false)() @system 
{
    uint result;
    static if(mem){
        mixin(`asm{"MRS %0, `,reg,`" : "=r" (result)::"memory";}`);
    }else{
        mixin(`asm{"MRS %0, `,reg,`" : "=r" (result);}`);
    }
    return result;
}
*/
/// 写入指定寄存器
void __setReg(string regName)(in uint val)
{
    __asm("msr "~regName~",$0","r",val);
}

/*
void __setReg(string reg,bool mem = false)(in uint val) @system 
{
    static if(mem){
        mixin(`asm{"MSR `,reg,`, %0" : : "r" (val) : "memory";}`);
    }else{
        mixin(`asm{"MSR `,reg,`, %0" : : "r" (val);}`);
    }
    
}
*/


/// 读取指定寄存器模板
uint __getVReg(string regName)()
{
    return __asm!uint("vmrs $0,"~regName,"=r");
}

void __setVReg(string regName)(in uint val)
{
    __asm("vmsr "~regName~",$0","r",val);
}

/*
uint __getVReg(string reg,bool mem = false)() @system 
{
    uint result;
    static if(mem){
        mixin(`asm{"VMRS %0, `,reg,`" : "=r" (result)::"memory";}`);
    }else{
        mixin(`asm{"VMRS %0, `,reg,`" : "=r" (result);}`);
    }
    return result;
}
*/


/// 读取 CONTROL 寄存器
alias __get_Control = __getReg!"control";

/// 写入 CONTROL 寄存器
alias __set_Control = __setReg!"control";

/// 读取 IPSR 寄存器
alias __get_IPSR = __getReg!"ipsr";

/// 读取 APSR 寄存器
alias __get_APSR = __getReg!"apsr";

/// 读取 xPSR 寄存器
alias __get_xPSR = __getReg!"xpsr";

/// 读取 PSP 寄存器
alias __get_PSP = __getReg!"psp";

/// 写入 PSP 寄存器
alias __set_PSP = __setReg!"psp";

/// 读取 MSP 寄存器
alias __get_MSP = __getReg!"msp";

/// 写入 MSP 寄存器
alias __set_MSP = __setReg!"msp";

/// 读取 PRIMASK 寄存器 (优先级掩码)
alias __get_PRIMASK = __getReg!("primask");

/// 设置 PRIMASK 寄存器 (优先级掩码)
alias __set_PRIMASK = __setReg!("primask");

/// 读取 BASEPRI 寄存器 (基本优先级掩码)
alias __get_BASEPRI = __getReg!"basepri";

/// 设置 BASEPRI 寄存器 (基本优先级掩码)
alias __set_BASEPRI = __setReg!"basepri";

/// 读取 BASEPRI_MAX 寄存器 (基本优先级最大值)
alias __get_BASEPRI_MAX = __getReg!"basepri_max";

/// 设置 BASEPRI_MAX 寄存器 (基本优先级最大值)
alias __set_BASEPRI_MAX = __setReg!"basepri_max";

/// 读取 FAULTMASK 寄存器 (故障掩码)
alias __get_FAULTMASK = __getReg!"faultmask";

/// 设置 FAULTMASK 寄存器 (故障掩码)
alias __set_FAULTMASK = __setReg!"faultmask";

static if(!__traits(targetHasFeature,"armv8-m.main"))
{
    /// 读取 PSPLIM 寄存器 (进程堆栈限制)
    alias __get_PSPLIM = __getReg!"psplim";

    /// 设置 PSPLIM 寄存器 (进程堆栈限制)
    alias __set_PSPLIM = __setReg!"psplim";

    /// 读取 MSPLIM 寄存器 (主堆栈限制)
    alias __get_MSPLIM = __getReg!"msplim";

    /// 设置 MSPLIM 寄存器 (主堆栈限制)
    alias __set_MSPLIM = __setReg!"msplim";
}


/// 读取 FPSCR 寄存器 (浮点状态和控制寄存器)
alias __get_FPSCR = __builtin_arm_get_fpscr;

/// 设置 FPSCR 寄存器 (浮点状态和控制寄存器)
alias __set_FPSCR = __builtin_arm_set_fpscr;


/// 读取 CPSR 寄存器
alias __get_CPSR = __getReg!"cpsr";

/// 读取 FPEXC 寄存器 (浮点扩展寄存器)
alias __get_FPEXC = __getVReg!"fpexc";